library ieee;
use ieee.std_logic_1164.all; 
use ieee.std_logic_arith.all; 
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity memorybank is
port(
		clk: in std_ulogic;
		flag: in std_ulogic;
		flag1: in std_ulogic; --********cup iteration enable flag
		flag2: in std_ulogic; --********vup iteration enable flag
		addr_cr: in std_ulogic_vector(7 downto 0);
		addr_cw: in std_ulogic_vector(7 downto 0);
		addr_vr: in std_ulogic_vector(6 downto 0);
		addr_vw: in std_ulogic_vector(6 downto 0);
		e_in: in std_ulogic_vector(15 downto 0);
		e_out: out std_ulogic_vector(31 downto 0);
		q_in: in std_ulogic_vector(31 downto 0);
		q_out: out std_ulogic_vector(15 downto 0)
		);
end memorybank;

architecture beh of memorybank is 
	component rf128x32mux2 is port(
            q   : out std_logic_vector(31 downto 0);
	          clk : in std_logic;
	          cen : in std_logic;
	          wen : in std_logic;
		  bwen : in std_ulogic_vector(31 downto 0);
	          a   : in std_logic_vector(6 downto 0);
	          d   : in std_logic_vector(31 downto 0)

	  );
	end component ;
	signal qe,de,qq,dq : std_logic_vector(31 downto 0);
	signal cenq,cene:std_logic;
	signal wenq,wene:std_logic_vector(1 downto 0);
	signal aq, ae:std_logic_vector(6 downto 0);
	signal addr_temp : std_ulogic_vector(7 downto 0);
       signal wenqq,wenee,cenb:std_logic;
       signal wenb:std_logic_vector(1 downto 0);
       signal ab : std_logic_vector(6 downto 0);
       signal db :std_logic_vector(31 downto 0);
       signal bwenq ,bwene :std_ulogic_vector(31 downto 0);
        
begin 
cenb <= '1' ;
wenb <= "11";
db <= (others => '0');
ab <= (others => '0');
process (clk)
  begin 
    if clk'event and clk = '1' then 
      addr_temp <= addr_cr;
    end if;
  end process;
  process (flag, flag1, flag2 , addr_cr,addr_cw,addr_vr,addr_vw,addr_temp,qq,e_in,q_in,qe)
  begin 
         if flag1 = '1' then  --cup is working
		 cene <= '0' ;
		 cenq <= '0' ;
		 wenqq <= '1';
		 wenee <= '0';
    if  addr_temp(0) = '0' then -- read the low 16bits
			wenq(0) <= '1';
			wenq(1) <= '1';
			q_out   <= std_ulogic_vector(qq(15 downto 0)); 
		else --read the high 16bit
			wenq(1) <= '1';
			wenq(0) <= '1';
			q_out   <= std_ulogic_vector(qq (31 downto 16));
    end if;		
		aq <= std_logic_vector(addr_cr(7 downto 1));
		--dq <= (others => '0');     -- do not write q_ram 
		if  addr_cw(0) = '0' then  --write the low 16 bit
			wene(0) <= '0';
			wene(1) <= '1';
			de(31 downto 0) <= std_logic_vector("0000000000000000" & e_in);
		else                       --write the high 16bit
			 wene(0) <= '1';
			 wene(1) <= '0';
       de(31 downto 0) <= std_logic_vector( e_in & "0000000000000000" );
		end if;
		ae <= std_logic_vector(addr_cw(7 downto 1));
	  elsif flag2 = '1' then 	
               cene <= '0' ;
	       cenq <= '0' ;
	       wenq <= "00";
	       wenqq <= '0';
		     wenee <= '1';
	       aq <= std_logic_vector(addr_vw); 
	       ae <= std_logic_vector(addr_vr);
   	      
	       de <= (others => '0');
               wene <= "11";
	       
	       q_out <= (others =>'0');
       else
	       cene <= '1' ;
	       cenq <= '1' ;
	       wenq <= "00";
	       wene <= "00";
	       wenqq <= '1';
	       wenee <= '1';
	       q_out <= (others =>'0');
	       aq <= (others => '0');
	       ae <= (others => '0');
	       de <= (others => '0');
	 end if;
  end process;
e_out <= std_ulogic_vector(qe);	
dq <= std_logic_vector(q_in);
bwenq(31 downto 16)  <=  wenq(1) & wenq(1) &  wenq(1)  &  wenq(1)  &  wenq(1)  &  wenq(1)  &  wenq(1)  &  wenq(1)  &  wenq(1)  &  wenq(1)  &  wenq(1)  &  wenq(1)  &  wenq(1)  &  wenq(1)  &  wenq(1)  &  wenq(1);
bwenq(15 downto 0 )  <=  wenq(0) & wenq(0) &  wenq(0)  &  wenq(0)  &  wenq(0)  &  wenq(0)  &  wenq(0)  &  wenq(0)  &  wenq(0)  &  wenq(0)  &  wenq(0)  &  wenq(0)  &  wenq(0)  &  wenq(0)  &  wenq(0)  &  wenq(0);
bwene(31 downto 16)  <=  wene(1) & wene(1) &  wene(1)  &  wene(1)  &  wene(1)  &  wene(1)  &  wene(1)  &  wene(1)  &  wene(1)  &  wene(1)  &  wene(1)  &  wene(1)  &  wene(1)  &  wene(1)  &  wene(1)  &  wene(1);
bwene(15 downto 0)   <=  wene(0) & wene(0) &  wene(0)  &  wene(0)  &  wene(0)  &  wene(0)  &  wene(0)  &  wene(0)  &  wene(0)  &  wene(0)  &  wene(0)  &  wene(0)  &  wene(0)  &  wene(0)  &  wene(0)  &  wene(0);

   ram_q :  rf128x32mux2  port map (q => qq,
                            clk => clk,
                            cen => cenq,
                            wen => wenqq,
			    bwen => bwenq,
                            a => aq,
                            d => dq);
   ram_e :  rf128x32mux2  port map (q => qe,
                            clk => clk,
                            cen => cene,
                            wen => wenee,
			      bwen => bwene,
                            a => ae,
                            d => de);
end beh ;  
